package cn.exrick.xboot.base.serviceimpl

import cn.exrick.xboot.base.dto.SecurityAdvisorDto
import cn.exrick.xboot.base.entity.EnterpriseUser
import cn.exrick.xboot.base.entity.SecurityAdvisor
import cn.exrick.xboot.base.entity.SecurityAdvisorServiceEnterprise
import cn.exrick.xboot.base.entity.SupervisionUser
import cn.exrick.xboot.base.mapper.SecurityAdvisorMapper
import cn.exrick.xboot.base.service.*
import cn.exrick.xboot.base.vo.*
import cn.exrick.xboot.core.common.constant.CommonConstant
import cn.exrick.xboot.core.common.utils.PageUtil
import cn.exrick.xboot.core.common.utils.ResultUtil
import cn.exrick.xboot.core.common.utils.SecurityUtil
import cn.exrick.xboot.core.common.utils.ToolUtil
import cn.exrick.xboot.core.common.vo.PageVo
import cn.exrick.xboot.core.common.vo.Result
import cn.exrick.xboot.core.entity.User
import cn.exrick.xboot.core.entity.UserRole
import cn.exrick.xboot.core.service.RoleService
import cn.exrick.xboot.core.service.UserService
import cn.exrick.xboot.core.service.mybatis.IUserRoleService
import cn.hutool.core.date.DateUtil
import com.baomidou.mybatisplus.extension.kotlin.KtQueryWrapper
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl
import com.google.common.collect.Maps
import lombok.extern.slf4j.Slf4j
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.data.redis.core.StringRedisTemplate
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional

/**
 * 安全顾问接口实现
 * @author Fei
 */
@Slf4j
@Service
@Transactional
open class ISecurityAdvisorServiceImpl : ServiceImpl<SecurityAdvisorMapper?, SecurityAdvisor?>(), ISecurityAdvisorService {


    @Autowired
    private var securityUtil:SecurityUtil? = null

    @Autowired
    private var userService:UserService? = null

    @Autowired
    private var iAreaService: IAreaService? = null

    @Autowired
    private val iUserRoleService: IUserRoleService? = null

    @Autowired
    private lateinit var roleService: RoleService

    @Autowired
    private lateinit var iBusinessService: IBusinessService

    @Autowired
    private lateinit var iSecurityAdvisorServiceEnterpriseService: ISecurityAdvisorServiceEnterpriseService

    @Autowired
    private lateinit var iSupervisionUserService: ISupervisionUserService

    @Autowired
    private lateinit var iEnterpriseUserService: IEnterpriseUserService

    @Autowired
    private lateinit var redisTemplate: StringRedisTemplate



    override fun createSecurityAdvisor(securityAdvisorDto: SecurityAdvisorDto?): Result<Any?>? {

       return securityAdvisorDto?.let {

            //添加用户
            val userInsert = userService!!.save(User().apply {

                ToolUtil.copyProperties(it, this)
                username = it.mobile
                password = BCryptPasswordEncoder().encode(it.password)
                birth = DateUtil.parse(it.birth)
                areaId = securityUtil!!.currUser.areaId
            })

            //添加角色
            iUserRoleService!!.save(UserRole().apply {

                userId = userInsert.id
                roleId = roleService.getRoleIdByRoleName("ROLE_SECURITY")
            })

            //添加安全顾问
            save(SecurityAdvisor().apply {

                ToolUtil.copyProperties(it, this)
                this.userId = userInsert.id
                areaId = userInsert.areaId
            })

           ResultUtil.success("添加监管部门成功！")
        }
    }

    override fun updateSecurityAdvisor(securityAdvisorDto: SecurityAdvisorDto): Result<Any?>? {

        return getById(securityAdvisorDto.id)?.run {

                //1.更新用户
                userService!!.get(userId)?.let {

                    ToolUtil.copyProperties(securityAdvisorDto, it)
                    it.id = userId!!
                    userService!!.update(it)
                    redisTemplate.delete("user::" + it.username)

                }

                //2. 更新安全顾问
                ToolUtil.copyProperties(securityAdvisorDto, this)
                updateById(this)

                ResultUtil.success<Any?>("更新成功")
            } ?: ResultUtil.error("当前用户不存在")
    }

    override fun removeSecurityAdvisor(ids: Array<out String>?): Result<Any?>? {

        return ids?.run {

            //遍历移除
            ids.forEach {

                //1.移除用户
                getById(it)?.run {

                    userService!!.delete(this.userId)

                    //2.移除监管部门
                    removeById(it)
                }
            }

            ResultUtil.success<Any>("移除成功")
        } ?: ResultUtil.error("参数缺失")
    }

    override fun forbiddenSecurityAdvisor(ids: Array<out String>?): Result<Any?>? {

        return ids?.run {

            this.toMutableList().forEach {

                getById(it)?.let {

                    userService!!.get(it.userId)?.apply {

                        when (this.status) {

                            CommonConstant.STATUS_DISABLE -> {

                                this.status = CommonConstant.STATUS_NORMAL
                            }
                            else -> {

                                this.status = CommonConstant.STATUS_DISABLE
                            }
                        }

                        userService!!.update(this)
                    }
                }
            }
            ResultUtil.success<Any?>("设置成功")
        } ?: ResultUtil.error("参数缺失")
    }

    override fun securityAdvisorList(pageVo: PageVo): Result<MutableMap<String, Any?>?>? {

       return ToolUtil.setListToNul(list(KtQueryWrapper(SecurityAdvisor::class.java).orderByAsc(SecurityAdvisor::createTime)))?.let { it ->

           var securityAdvisorVoList = it.map { securityAdvisor -> getSecurityAdvisorVo(securityAdvisor?.id) }.toMutableList()

            if (!iUserRoleService!!.findByUserId(securityUtil!!.currUser.id).map { it.id }.contains(CommonConstant.ROLE_ADMIN))
                securityAdvisorVoList = securityAdvisorVoList.filter { securityAdvisorVo -> securityAdvisorVo!!.areaId!! == securityUtil!!.currUser.areaId }.toMutableList()


            val result: MutableMap<String, Any?> = Maps.newHashMap()

            result["size"] = securityAdvisorVoList.size
            result["content"] = PageUtil.listToPage(pageVo, securityAdvisorVoList)

            ResultUtil.data(result, "获取安全顾问列表成功")
        } ?: ResultUtil.error(201, "暂无数据")
    }

    override fun getSecurityAdvisorListByAreaId(pageVo: PageVo): Result<MutableMap<String, Any?>?>? {

        return ToolUtil.setListToNul(list(KtQueryWrapper(SecurityAdvisor::class.java)
                .eq(SecurityAdvisor::areaId, securityUtil!!.currUser.areaId)
                .orderByDesc(SecurityAdvisor::createTime)))?.let { it ->

            var securityAdvisorVoList = it.map { securityAdvisor -> getSecurityAdvisorVo(securityAdvisor?.id) }.toMutableList()

            if (!iUserRoleService!!.findByUserId(securityUtil!!.currUser.id).map { it.id }.contains(CommonConstant.ROLE_ADMIN))
                securityAdvisorVoList = securityAdvisorVoList.filter { securityAdvisorVo -> securityAdvisorVo!!.areaId!! == securityUtil!!.currUser.areaId }.toMutableList()


            val result: MutableMap<String, Any?> = Maps.newHashMap()

            result["size"] = securityAdvisorVoList.size
            result["content"] = PageUtil.listToPage(pageVo, securityAdvisorVoList)

            ResultUtil.data(result, "获取安全顾问列表成功")
        } ?: ResultUtil.error(201, "暂无数据")

    }

    override fun getSupervisionListByAreaId(): Result<List<UserCommonVo>> {

       return ToolUtil.setListToNul(iSupervisionUserService.list(KtQueryWrapper(SupervisionUser::class.java).eq(SupervisionUser::areaId, securityUtil!!.currUser.areaId)
               .orderByDesc(SupervisionUser::createTime)).filter { iUserRoleService!!.findByUserId(it!!.userId).map { it.id }.contains(when (iAreaService!!.getById(securityUtil!!.currUser.areaId)?.areaLevel) {

           2 -> {
               CommonConstant.ROLE_COUNTY_REPORT
           }
           else -> {
               CommonConstant.ROLE_TOWN_REPORT
           }
       }) })?.run {

            return ResultUtil.data(mapNotNull {
                UserCommonVo().apply {

                    userService!!.get(it!!.userId)?.let {
                        ToolUtil.copyProperties(it, this)
                    }
                }
            }, "获取成功")
        } ?: ResultUtil.error<List<UserCommonVo>>(201, "暂无数据")
    }

    override fun getEnterpriseListByAreaId(pageVo: PageVo, areaId: String?): Result<MutableMap<String, Any?>?>? {

        return ToolUtil.setListToNul(iEnterpriseUserService.list(KtQueryWrapper(EnterpriseUser::class.java)
                .eq(ToolUtil.isNotEmpty(areaId), EnterpriseUser::areaId, securityUtil!!.currUser.areaId)
                .orderByDesc(EnterpriseUser::createTime)))?.run {

            val result: MutableMap<String, Any?> = Maps.newHashMap()
            result["size"] = size
            result["content"] = PageUtil.listToPage(pageVo, mapNotNull { iEnterpriseUserService.getEnterpriseUserVo(it!!.id) }.toMutableList())
            ResultUtil.data(result, "获取数据成功")
        } ?: ResultUtil.error(201, "暂无数据")
    }


    override fun getSecurityAdvisorVo(id: String?): SecurityAdvisorVo? {

       return getById(id!!)?.let {

           SecurityAdvisorVo().apply {

               userService!!.get(it.userId)?.let { user ->

                   ToolUtil.copyProperties(user, this)
                   areaName = iAreaService!!.getAreaFullNameByAreaId(areaId)

                   ToolUtil.copyProperties(it, this)
                   businessIdNameList = it.businessIds?.run { iBusinessService.listByIds(split(","))
                           .mapNotNull { business -> business?.businessName }.joinToString(",") }
                   businessIds = it.businessIds?.split(",")?.toMutableList()
                   nickname = user.nickname
               }
           }
        }
    }

    override fun getSecurityAdvisorListVo(id: String): SecurityAdvisorListVo? {

       return getById(id)?.run {

            SecurityAdvisorListVo().apply {

                userService!!.get(userId).let { ToolUtil.copyProperties(it, this) }
                businessName = businessIds?.run { iBusinessService.listByIds(split(",")).mapNotNull { business -> business?.businessName }.joinToString(",")  }
                businessNameList = businessIds?.run { iBusinessService.listByIds(split(",")).mapNotNull { business -> business?.businessName }.toMutableList() }
                companyType = iSecurityAdvisorServiceEnterpriseService.getCompanyTypeBySecurityAdvisorId(userId!!)
                this.id = this@run.id
            }
        }
    }

    override fun getSecurityAdvisorDetailVo(id: String): SecurityAdvisorDetailVo? {

       return getById(id)?.run {

            SecurityAdvisorDetailVo().apply {

                securityAdvisorListVo = getSecurityAdvisorListVo(id)

                iSecurityAdvisorServiceEnterpriseService.getOne(KtQueryWrapper(SecurityAdvisorServiceEnterprise::class.java).eq(SecurityAdvisorServiceEnterprise::createBy, userId)
                        .orderByAsc(SecurityAdvisorServiceEnterprise::createTime).last("limit 1"))?.let {
                    serviceBeginTime = it.serviceBeginTime
                    serviceEndTime = it.serviceEndTime
                }

                businessName =  businessIds?.run { iBusinessService.listByIds(split(",")).mapNotNull { business -> business?.businessName }.joinToString(" ")  }
                email = userService!!.get(userId)?.email
                enterpriseUserListVo = iSecurityAdvisorServiceEnterpriseService.getSecurityAdvisorLeaveEnterprise(userId!!)
            }
        }
    }

    override fun getSecurityEnterpriseAdvisorListVO(securityUserId: String): EnterpriseSecurityAdvisorListVo? {

       return EnterpriseSecurityAdvisorListVo().apply {

            userService!!.get(securityUserId)?.let {

                ToolUtil.copyProperties(it, this)

                //roleName = iUserRoleService!!.findByUserId(securityUserId)?.joinToString(",") { it.description }

                getOne(KtQueryWrapper(SecurityAdvisor::class.java).eq(SecurityAdvisor::userId, securityUserId))?.let {

                    introduction = it.introduction
                    id = it.id
                }

                iSecurityAdvisorServiceEnterpriseService.list(KtQueryWrapper(SecurityAdvisorServiceEnterprise::class.java).eq(SecurityAdvisorServiceEnterprise::createBy, securityUserId)
                        .eq(SecurityAdvisorServiceEnterprise::serviceStatus, true))?.let {

                    serviceEnterprise = it.map { iEnterpriseUserService.getById(it!!.enterpriseUserId)?.companyName }.toMutableList()
                }
            }

        }
    }

    override fun getUserIdBySecurityId(securityId: String): String? {

        return getById(securityId)?.userId
    }

    override fun getSecurityAdvisorInfo(): Result<SecurityAdvisorInfoVo?>? {

       return ResultUtil.data(SecurityAdvisorInfoVo().apply {

           //1. 用户信息
           ToolUtil.copyProperties(securityUtil!!.currUser, this)

           //2.安全顾问信息
           getOne(KtQueryWrapper(SecurityAdvisor::class.java).eq(SecurityAdvisor::userId, securityUtil!!.currUser.id))?.let {

               ToolUtil.copyProperties(it, this)
               businessNameList = it.businessIds?.split(",")?.mapNotNull { iBusinessService.getBusinessNameById(it) }?.toMutableList()
               selfPicList = it.selfPic?.split(",")
               addressDetail = iAreaService!!.getAreaFullNameByAreaId(areaId)?.plus(securityUtil!!.currUser.street)
               roleName = iUserRoleService!!.findByUserId(securityUtil!!.currUser.id).map { it.name }.joinToString(",")
           }
       }, "获取安全顾问个人信息成功！")
    }
}
